package indi.mozping.synchronizedp.biasedlock;

import org.openjdk.jol.info.ClassLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * @author by mozping
 * @Classname Test1
 * @Description 测试批量撤销
 * -XX:BiasedLockingStartupDelay=0  -XX:+PrintFlagsFinal
 * @Date 2020/1/14 20:37
 */
public class Test2 {

    static final int SIZE = 50;

    public static void main(String[] args) throws Exception {

        System.out.println("=====================================");
        {
            LockObject a = new LockObject();
            System.out.println((ClassLayout.parseInstance(a).toPrintable()));
            Thread.sleep(100);
        }

        //创造锁对象
        List<LockObject> listA = new ArrayList<>();
        for (int i = 0; i < SIZE; i++) {
            LockObject a = new LockObject();
            listA.add(a);
            System.out.println("Init state ,The " + (i + 1) + "th object head");
            System.out.println((ClassLayout.parseInstance(a).toPrintable()));
        }

        //延时产生可偏向对象,实际上设置了-XX:BiasedLockingStartupDelay=0后，立即就会启动偏向锁机制
        Thread.sleep(1000);

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < SIZE; i++) {
                LockObject a = listA.get(i);
                synchronized (a) {
                    System.out.print(" ");
                }
            }
            try {
                //为了防止JVM线程复用，在创建完对象后，保持线程t1状态为存活
                Thread.sleep(100000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();


        //睡眠3s钟保证线程t1创建对象完成
        Thread.sleep(3000);
        for (int i = 0; i < SIZE; i++) {
            LockObject a = listA.get(i);
            //打印偏向锁重偏向结果
            System.out.println("Thread t1 ,The " + (i + 1) + "th object head");
            System.out.println((ClassLayout.parseInstance(a).toPrintable()));
        }

        System.out.println("=====================================");

        //创建线程t2竞争线程t1中已经退出同步块的锁
        Thread t2 = new Thread(() -> {
            //线程2竞争偏向锁，导致后面的锁偏向线程2
            for (int i = 0; i < SIZE; i++) {
                LockObject a = listA.get(i);
                synchronized (a) {
                    //打印偏向锁重偏向结果
                    System.out.println("Thread t2 ,The " + (i + 1) + "th biased result");
                    System.out.println((ClassLayout.parseInstance(a).toPrintable()));
                }
            }
            try {
                Thread.sleep(10000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t2.start();

        Thread.sleep(3000);
        System.out.println("=====================================");
        //线程3继续撤销锁
        Thread t3 = new Thread(() -> {
            //线程2竞争偏向锁，导致后面的锁偏向线程2
            for (int i = 20; i < SIZE; i++) {
                LockObject a = listA.get(i);
                synchronized (a) {
                    //打印偏向锁重偏向结果
                    System.out.println("Thread t3 ,The " + (i + 1) + "th biased result");
                    System.out.println((ClassLayout.parseInstance(a).toPrintable()));
                }
            }
            try {
                Thread.sleep(10000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t3.start();

        Thread.sleep(3000);
        System.out.println("=====================================");
        LockObject a = new LockObject();
        System.out.println((ClassLayout.parseInstance(a).toPrintable()));
        //睡眠3s钟保证线程t1创建对象完成
//        Thread.sleep(3000);
//        System.out.println("=====================================");
//        //使用LockObject类的新的对象加锁,理论上应该是轻量级锁了
//        for (int i = 1000; i < 1010; i++) {
//            final int index = i;
//            LockObject a = new LockObject();
//            Thread tmp = new Thread(() -> {
//                synchronized (a) {
//                    //打印偏向锁重偏向结果
//                    System.out.println("Thread t" + index + " ,The " + (index + 1) + "th biased result");
//                    System.out.println((ClassLayout.parseInstance(a).toPrintable()));
//                }
//                try {
//                    Thread.sleep(100000000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }, "t" + index);
//            tmp.start();
//            Thread.sleep(1000);
//        }
//
//        Thread.sleep(3000);
    }
}